# -*- coding:UTF-8 -*-#

'''
@author: qianwp
'''
from popcan.core.structures import Singleton
from popcan.globals.settings import RedisSettings
from popcan.cache.cachebase import IoBuffer
from popcan.cache.cachebase import CacheObject
from popcan.helper.picklehelper import YamlHelper
from popcan.helper.picklehelper import CPickleHelper
from popcan.helper.loggerhelper import QueueLogger,Module
from popcan.core.exceptions import RedisAccessError
import traceback

class RedisObject(CacheObject):
    pass

#考虑要不要将redis和memcache的api合并到一块去
class RedisLinker(Singleton):
    
    def __init__(self,redisclient):
        self.client = redisclient
    
    def incr(self,key,value):
        self.client.incr(key,value)
        
    def __setitem__(self,key,value):
        print key,value
        self.client.set(key,value)
        
    def __getitem__(self,key):
        print key
        return self.client.get(key)
    
    def __delitem__(self,key):
        return self.client.delete(key)
        
    def pipeline(self):
        return self.client.pipeline()
    
    def begin(self):
        if RedisSettings.pipeline:
            redis = RedisLinker().pipeline()
        else:
            redis = RedisLinker()
        return redis
    
    def end(self,redis):
        if RedisSettings.pipeline:
            redis.execute()
            
    def close(self):
        self.client.shutdown()
            
class BaseRedisDao(Singleton):
    
    def __init__(self,linker,itemClass):
        self.linker = linker
        self.itemClass = itemClass
        self.marshal = CPickleHelper()
        self.pickle = YamlHelper()
        
    def save(self,cacheitem):
        try:
            buf = IoBuffer()
            cacheitem.write(buf)
            self.linker[cacheitem.key()] = self.encode(buf.getBuffer())
        except:
            QueueLogger().error(Module.Redis, 'save failure cacheitem=%s' % self.pickle.dump(cacheitem), traceback.format_exc())
            raise RedisAccessError('save','save %s failure' % self.itemClass)

    def get(self,key):
        try:
            rawbyte = self.linker[self.itemClass.cachekey(key)]
            if rawbyte is None:
                return None
            buf = IoBuffer(self.decode(rawbyte))
            target = self.itemClass()
            target.read(buf)
            return target
        except:
            QueueLogger().error(Module.Redis, 'get failure key=%s' % key, traceback.format_exc())
            raise RedisAccessError('get','get %s failure' % self.itemClass)
    
    def delete(self,key):
        try:
            del self.linker[self.itemClass.cachekey(key)]
        except:
            QueueLogger().error(Module.Redis, 'delete failure key=%s' % key, traceback.format_exc())
            raise RedisAccessError('delete','delete %s failure' % self.itemClass)
        
    def encode(self,listbuf):
        return self.marshal.dump(listbuf)
    
    def decode(self,rawbytes):
        return self.marshal.load(rawbytes)